#include "device.h"
void Device::init()
{
	SFFDISK_DEVICE_COMMAND_DATA* psdcd = (SFFDISK_DEVICE_COMMAND_DATA*)&_buffer.sdcd[0];
    psdcd->HeaderSize = sizeof(SFFDISK_DEVICE_COMMAND_DATA);
    psdcd->Command = SFFDISK_DC_DEVICE_COMMAND;
    psdcd->ProtocolArgumentSize = sizeof(SDCMD_DESCRIPTOR);
    psdcd->DeviceDataBufferSize = 16;

    _buffer.desc.Cmd = SDCMD_SEND_CSD;
    _buffer.desc.CmdClass = SDCC_STANDARD;
    _buffer.desc.TransferDirection = SDTD_READ;
    _buffer.desc.TransferType = SDTT_CMD_ONLY;
    _buffer.desc.ResponseType = SDRT_2;
}

Device::Device(wchar_t drive_number)
{
	
    std::wostringstream mount_point;
    mount_point << drive_number << L":\\";
	if(::GetVolumeNameForVolumeMountPoint(
           mount_point.str().c_str(),
           _volume,
           MAX_PATH)){
			   
        size_t length = wcslen(_volume);
        if(_volume[length-1] == L'\\'){
            _volume[length-1] = 0;
        }

		_handle = ::CreateFile(_volume,GENERIC_READ|GENERIC_WRITE,
                             FILE_SHARE_READ|FILE_SHARE_WRITE
                             ,NULL,OPEN_EXISTING,
                             FILE_FLAG_NO_BUFFERING,NULL);
        if( INVALID_HANDLE_VALUE == _handle){
            std::wstring str(L"Fail to open: ");
            str += mount_point.str();
            throw no_device_exception(str);
        }

    }else{
        std::wstring str(L"Cannot get volume for: ");
        str += mount_point.str();
        throw no_volume_exception(str);
    }
}

BOOL Device::IsSdCard()
{
    init();
    DWORD ret_size;
	return ::DeviceIoControl(_handle,
                           IOCTL_SFFDISK_DEVICE_COMMAND,
                           (LPVOID)&_buffer,
                           sizeof(cmd_buffer),
                           (LPVOID)&_buffer,
                           sizeof(cmd_buffer),
                           &ret_size,
                           0);
}
